import 'package:backend.purchases/domain/entities/yookassa_api/payments/yookassa_api_succeeded_payment.dart';
import 'package:backend.purchases/domain/entities/yookassa_api/payments/yookassa_api_succeeded_payment_method.dart';
import 'package:backend.purchases/infrastructure/dtos/yookassa_api/payments/succeeded_payment/yookassa_api_succeeded_payment_method_dto.dart';
import 'package:backend.purchases/infrastructure/dtos/yookassa_api/payments/yookassa_api_payment_dto.dart';
import 'package:backend.purchases/infrastructure/dtos/yookassa_api/payments/yookassa_api_payment_meta_dto.dart';
import 'package:backend.purchases/infrastructure/dtos/yookassa_api/yookassa_api_money_amount_dto.dart';
import 'package:backend.purchases/infrastructure/dtos/yookassa_api/yookassa_api_time_dto.dart';

const kYookassaApiSucceededPaymentRefundedAmountKey = 'refunded_amount';
const kYookassaApiSucceededPaymentTimeKey = 'captured_at';
const kYookassaApiSucceededPaymentIncomeAmountKey = 'income_amount';
const kYookassaApiSucceededPaymentMethodKey = 'payment_method';

const kYookassaApiSucceededPaymentTypeValue = 'succeeded';

class YookassaApiSucceededPaymentDto extends YookassaApiPaymentDto {
  const YookassaApiSucceededPaymentDto._internal({
    required this.id,
    required this.amountDto,
    required this.metadataDto,
    required this.test,
    required this.refundedAmountDto,
    required this.paymentTimeDto,
    required this.incomeAmountDto,
    required this.paymentMethodDto,
  });

  @override
  final String id;

  @override
  final YookassaApiMoneyAmountDto amountDto;

  @override
  final YookassaApiPaymentMetadataDto metadataDto;

  @override
  final bool test;

  final YookassaApiMoneyAmountDto refundedAmountDto;
  final YookassaApiTimeDto paymentTimeDto;
  final YookassaApiMoneyAmountDto incomeAmountDto;
  final YookassaApiSucceededPaymentMethodDto paymentMethodDto;

  @override
  String get type => kYookassaApiSucceededPaymentTypeValue;

  @override
  List<Object?> get props {
    return [
      id,
      amountDto,
      metadataDto,
      test,
      refundedAmountDto,
      paymentTimeDto,
      incomeAmountDto,
      paymentMethodDto,
    ];
  }

  factory YookassaApiSucceededPaymentDto.fromJson(Map<String, dynamic> json) {
    final metadataJson = json[kYookassaApiPaymentMetadataKey];
    final metadataDto = YookassaApiPaymentMetadataDto.fromJson(metadataJson);

    final amountJson = json[kYookassaApiPaymentAmountKey];
    final amountDto = YookassaApiMoneyAmountDto.fromJson(amountJson);

    final refundedAmountJson = json[kYookassaApiSucceededPaymentRefundedAmountKey];
    final refundedAmountDto = YookassaApiMoneyAmountDto.fromJson(refundedAmountJson);

    final paymentTimeString = json[kYookassaApiSucceededPaymentTimeKey];
    final paymentTimeDto = YookassaApiTimeDto.fromString(paymentTimeString);

    final incomeAmountJson = json[kYookassaApiSucceededPaymentIncomeAmountKey];
    final incomeAmountDto = YookassaApiMoneyAmountDto.fromJson(incomeAmountJson);

    final paymentMethodJson = json[kYookassaApiSucceededPaymentMethodKey];
    final paymentMethodDto = YookassaApiSucceededPaymentMethodDto.fromJson(paymentMethodJson);

    return YookassaApiSucceededPaymentDto._internal(
      id: json[kYookassaApiPaymentIdKey],
      amountDto: amountDto,
      metadataDto: metadataDto,
      test: json[kYookassaApiPaymentTestKey],
      refundedAmountDto: refundedAmountDto,
      paymentTimeDto: paymentTimeDto,
      incomeAmountDto: incomeAmountDto,
      paymentMethodDto: paymentMethodDto,
    );
  }

  @override
  YookassaApiSucceededPayment toEntity() {
    final amount = amountDto.toEntity();
    final refundedAmount = refundedAmountDto.toEntity();
    final paymentTime = paymentTimeDto.toEntity();
    final incomeAmount = incomeAmountDto.toEntity();

    final paymentMethod = YookassaApiSucceededPaymentMethod(
      id: paymentMethodDto.id,
      saved: paymentMethodDto.saved,
      test: test,
      bankCardInfo: paymentMethodDto.bankCardInfoDto.toEntity(),
    );

    return YookassaApiSucceededPayment(
      id: id,
      amount: amount,
      purchaseItemSku: metadataDto.purchaseItemSku,
      userId: metadataDto.userId,
      savedPaymentMethodId: metadataDto.savedPaymentMethodId,
      test: test,
      refundedAmount: refundedAmount,
      paymentTime: paymentTime,
      incomeAmount: incomeAmount,
      paymentMethod: paymentMethod,
    );
  }
}
